package com.smile.frame.api.demo.base.interceptor;

import cn.hutool.json.JSONUtil;
import com.smile.frame.api.demo.base.permission.PermissionKeyFactory;
import com.smile.frame.api.demo.base.permission.PermissionKeyInterface;
import com.smile.frame.common.exception.BaseErrorCodeEnum;
import com.smile.frame.common.exception.ErrorCodeEnumInterface;
import com.smile.frame.common.result.Result;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.lang.reflect.Method;
import java.nio.charset.StandardCharsets;
import java.util.Map;

/**
 * 认证拦截器
 *
 * @author LGC
 * @date 2021/8/2 14:20

 */
@Slf4j
@Configuration
public class AuthInterceptor implements HandlerInterceptor {

//    @Resource
//    private AccountCacheService accountCacheService;

//    @Autowired
//    private RedisService redisService;
//    @Autowired
//    private RedissonClient redissonClient;

    public AuthInterceptor() {
    }

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        log.info("前置拦截");
        if (!(handler instanceof HandlerMethod)) {
            return true;
        }
        HandlerMethod handlerMethod = (HandlerMethod) handler;
        Method method = handlerMethod.getMethod();
        //判断如果请求的类是swagger的控制器，直接通行。
        if (handlerMethod.getBean().getClass().getName().equals("springfox.documentation.swagger.web.ApiResourceController")) {
            return true;
        }
        // 不需要认证直接跳过拦截
        UnAuthInterceptor unAuthInterceptor = method.getAnnotation(UnAuthInterceptor.class);
        if (unAuthInterceptor != null) {
            return true;
        }

        // token 验证是否登录
//        LoginCacheVO loginCache = accountCacheService.getLoginCache(request);
//        if (loginCache == null) {
//            unAuthenticationEntryPoint(response,BaseErrorCodeEnum.BASE_LOGIN_ERROR);
//            return false;
//        }

        String token = request.getHeader("Authorization");
        String ip = request.getRemoteAddr();
        String url = request.getRequestURI();
        log.info("token:{},ip:{},url:{}", token, ip, url);
        Map<String, PermissionKeyInterface> permissionKeyMaps = PermissionKeyFactory.urlMaps;
        PermissionKeyInterface permissionKeyInterface = permissionKeyMaps.get(url);
        log.info("permissionKeyInterface:{}", permissionKeyInterface);
//        if (permissionKeyInterface == null) {
//            unAuthenticationEntryPoint(response, BaseErrorCodeEnum.BASE_URL_404_ERROR);
//            log.info("请求地址尚未定义");
//            return false;
//        }

        // 权限验证
//        if (!permissionValidate(response, permissionKeyInterface)) {
//            return false;
//        }

        // 返回true才会继续执行，返回false则取消当前请求
        return true;
    }

    private boolean permissionValidate(HttpServletResponse response, PermissionKeyInterface permissionKeyInterface) throws IOException {
        String permission_key = permissionKeyInterface.getPermission_key();
        Boolean is_authority = permissionKeyInterface.getIs_authority();
        log.info("permission_key:{}", permission_key);
        if (permission_key == null) {
            log.info("对应url未找到permission_key");
            unAuthenticationEntryPoint(response, BaseErrorCodeEnum.BASE_NO_PERMISSION_ERROR);
            return false;
        }
        // 验证是否具有与权限
        if (is_authority) {
            log.info("对应url权限验证...");
//            Boolean result = authorityService.validatePermission(token, permission_key);
//            if (!result) {
//                log.info("对应url无权限");
//                unAuthenticationEntryPoint(response, BaseErrorCodeEnum.BASE_NO_PERMISSION_ERROR);
//                return false;
//            }
            log.info("对应url权限验证通过");
        } else {
            log.info("对应url无需权限验证");
        }
        return true;
    }


    private void unAuthenticationEntryPoint(HttpServletResponse response, ErrorCodeEnumInterface errorCodeEnumInterface) throws IOException {
        response.setHeader(HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN, "*");
        response.setHeader(HttpHeaders.CACHE_CONTROL, "no-cache");
        response.setCharacterEncoding(String.valueOf(StandardCharsets.UTF_8));
        response.setContentType(MediaType.APPLICATION_JSON_VALUE);
        response.getWriter().println(JSONUtil.parse(Result.error(errorCodeEnumInterface)));
        response.getWriter().flush();
    }

    /**
     * token + 当前请求地址，作为一个唯一KEY
     *
     * @param token token
     * @param path  请求路径
     * @return
     */
    private String getKey(String token, String ip, String path) {
        return token + "_" + ip + "_" + path;
    }
}
